﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Protocal.App.Common
{
    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;

    public static class EncryptHelper
    {
        #region 对称加密（AES）

        private static string aesKey = "MySecretKey12345MySecretIV123456"; // 32位
        private static string aesIV = "MySecretIV123456"; // 16位
        private static string md5Key = "abcdefghijklmnopqrstuvwxyz012345";

        static EncryptHelper()
        {
            aesKey = AppSetting.Get<string>("AesKey");
            aesIV = AppSetting.Get<string>("AesIV");
            md5Key = AppSetting.Get<string>("Md5");

        }

        public static string AesEncrypt(string plainText)
        {
            using var aes = Aes.Create();
            aes.Key = Encoding.UTF8.GetBytes(aesKey);
            aes.IV = Encoding.UTF8.GetBytes(aesIV);

            using var encryptor = aes.CreateEncryptor();
            using var ms = new MemoryStream();
            using var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
            using (var sw = new StreamWriter(cs))
            {
                sw.Write(plainText);
            }
            return Convert.ToBase64String(ms.ToArray());
        }

        public static string AesDecrypt(string cipherText)
        {
            using var aes = Aes.Create();
            aes.Key = Encoding.UTF8.GetBytes(aesKey);
            aes.IV = Encoding.UTF8.GetBytes(aesIV);

            using var decryptor = aes.CreateDecryptor();
            using var ms = new MemoryStream(Convert.FromBase64String(cipherText));
            using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
            using var sr = new StreamReader(cs);
            return sr.ReadToEnd();
        }

        #endregion

        #region 非对称加密（RSA）

        public static void GenerateRsaKey(out string publicKey, out string privateKey)
        {
            using var rsa = RSA.Create(2048);
            publicKey = Convert.ToBase64String(rsa.ExportRSAPublicKey());
            privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey());
        }

        public static string RsaEncrypt(string plainText, string base64PublicKey)
        {
            using var rsa = RSA.Create();
            rsa.ImportRSAPublicKey(Convert.FromBase64String(base64PublicKey), out _);
            var data = Encoding.UTF8.GetBytes(plainText);
            var encrypted = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
            return Convert.ToBase64String(encrypted);
        }

        public static string RsaDecrypt(string cipherText, string base64PrivateKey)
        {
            using var rsa = RSA.Create();
            rsa.ImportRSAPrivateKey(Convert.FromBase64String(base64PrivateKey), out _);
            var data = Convert.FromBase64String(cipherText);
            var decrypted = rsa.Decrypt(data, RSAEncryptionPadding.Pkcs1);
            return Encoding.UTF8.GetString(decrypted);
        }

        #endregion

        #region MD5 加密（不可逆）

        public static string Md5Encrypt(string plainText)
        {
            using var md5 = MD5.Create();
            //2  1 3 5 8 4 6 3
            string preText = plainText.Insert(2, md5Key.Substring(0, 2))
                .Insert(1, md5Key.Substring(2, 1))
                .Insert(3, md5Key.Substring(3, 3))
                .Insert(5, md5Key.Substring(6, 5))
                .Insert(8, md5Key.Substring(11, 8))
                .Insert(4, md5Key.Substring(19, 4))
                .Insert(6, md5Key.Substring(23, 6))
                .Insert(3, md5Key.Substring(29, 3));
            var bytes = Encoding.UTF8.GetBytes(preText);
            var hashBytes = md5.ComputeHash(bytes);
            var sb = new StringBuilder();
            foreach (var b in hashBytes)
            {
                sb.Append(b.ToString("x2")); // 16进制
            }
            return sb.ToString();
        }

        #endregion
    }

}
